package com.jht.bletool2java.activity.blepage.adapter;


import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;


import com.jht.bletool2java.R;
import com.jht.bletool2java.util.AttributeLookup;
import com.jht.bletool2java.widget.Rotate180ImageView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


public class ExpandableLvBTAdapter extends BaseExpandableListAdapter {

    private static final String TAG = "ExpandableLvBTAdapter";
    private Context context;
    private List<BluetoothGattService> servicesGroup = new ArrayList<>();
    private List<BluetoothGattCharacteristic> characteristicsChild = new ArrayList<>();
    private Map<String, List<BluetoothGattCharacteristic>> map = new HashMap<>();
    private AttributeLookup attributeLookup = null;
    private Callback callback;

    public interface Callback {

        void read(BluetoothGattCharacteristic characteristic);

        void write(BluetoothGattCharacteristic characteristic);

        void CharacteristicNotify(BluetoothGattCharacteristic characteristic);

        void CharacteristicIndicate(BluetoothGattCharacteristic characteristic);
        //关闭通知
        void closeNotify(BluetoothGattCharacteristic characteristic);
    }

    public Callback getCallback() {
        return callback;
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public ExpandableLvBTAdapter(Context context, List<BluetoothGattService> services, Map<String, List<BluetoothGattCharacteristic>> uuid_map_char) {
        this.context = context;
        attributeLookup = new AttributeLookup(context);

        servicesGroup = services;
        map =  uuid_map_char;
    }

    @Override
    public int getGroupCount() {
        return servicesGroup.size();
    }

    @Override
    public int getChildrenCount(int groupIndex) {
        String uuidStr = servicesGroup.get(groupIndex).getUuid().toString();
        return map.get(uuidStr).size();
    }

    @Override
    public Object getGroup(int groupIndex) {
        return servicesGroup.get(groupIndex);
    }

    @Override
    public Object getChild(int groupIndex, int childIndex) {
        String uuidStr = servicesGroup.get(groupIndex).getUuid().toString();
        return map.get(uuidStr).get(childIndex);
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    public void clearAllList() {
        servicesGroup.clear();
        characteristicsChild.clear();
        map.clear();
        notifyDataSetChanged();
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHolder groupViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_elv_group_service, parent, false);
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.mLlBtServiceInfo = convertView.findViewById(R.id.ll_bt_service_info);
            groupViewHolder.mTvBtServiceName = convertView.findViewById(R.id.tv_bt_service_name);
            groupViewHolder.mTvBtServiceUuid = convertView.findViewById(R.id.tv_bt_service_uuid);
            convertView.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) convertView.getTag();
        }
        UUID uuid = servicesGroup.get(groupPosition).getUuid();
        groupViewHolder.mTvBtServiceName.setText(attributeLookup.getService(uuid));
        groupViewHolder.mTvBtServiceUuid.setText(uuid.toString());
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildViewHolder childViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_elv_child_characteristic, parent, false);
            childViewHolder = new ChildViewHolder();
            childViewHolder.mTvBtCharName = convertView.findViewById(R.id.tv_bt_char_name);
            childViewHolder.mIvUpArrow = convertView.findViewById(R.id.iv_up_arrow);
            childViewHolder.mIvDownArrow = convertView.findViewById(R.id.iv_down_arrow);
            childViewHolder.mIvNotify = convertView.findViewById(R.id.iv_notify);
            childViewHolder.mTvBtCharUuid = convertView.findViewById(R.id.tv_bt_char_uuid);
            childViewHolder.mTvProperties = convertView.findViewById(R.id.tv_properties);

            convertView.setTag(childViewHolder);
        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        String uuidStr = servicesGroup.get(groupPosition).getUuid().toString();
        BluetoothGattCharacteristic bluetoothGattCharacteristic = map.get(uuidStr).get(childPosition);
        final UUID characteristic_uuid = bluetoothGattCharacteristic.getUuid();
        childViewHolder.mTvBtCharName.setText(attributeLookup.getCharacteristic(characteristic_uuid));
        childViewHolder.mTvBtCharUuid.setText(characteristic_uuid.toString());
        int properties = bluetoothGattCharacteristic.getProperties();
        String propertiesStr = getCharacterProperties(properties);
        childViewHolder.mTvProperties.setText(propertiesStr);

        // 判断该特征 可执行那些操作 读，写，通知。。。 这里有个问题： 就是 NOTIFY 和 INDICATE 属性不能同时出现（应该不会同时出现吧）
        childViewHolder.mIvUpArrow.setVisibility(View.GONE);
        childViewHolder.mIvDownArrow.setVisibility(View.GONE);
        childViewHolder.mIvNotify.setVisibility(View.GONE);

        final BluetoothGattCharacteristic characteristic = (BluetoothGattCharacteristic)getChild(groupPosition, childPosition);

        if (propertiesStr.contains("READ")){
            childViewHolder.mIvDownArrow.setVisibility(View.VISIBLE);
            childViewHolder.mIvDownArrow.setOnClickListener(new View.OnClickListener(){

                @Override
                public void onClick(final View v) {
                    if (callback != null){

                        callback.read(characteristic);
                    }
                }
            });

        }
        if (propertiesStr.contains("WRITE") || propertiesStr.contains("W_N_RESP")){
            childViewHolder.mIvUpArrow.setVisibility(View.VISIBLE);
            childViewHolder.mIvUpArrow.setOnClickListener(new View.OnClickListener(){

                @Override
                public void onClick(View v) {
                    if (callback != null){
                        callback.write(characteristic);
                    }
                }
            });
        }
        if(propertiesStr.contains("NOTIFY") || propertiesStr.contains("INDICATE")){
            childViewHolder.mIvNotify.setVisibility(View.VISIBLE);
            childViewHolder.mIvNotify.setOnClickListener(new View.OnClickListener(){
                private boolean isClick = false;
                @Override
                public void onClick(View v) {
                    if (callback != null){
                        if (!isClick){
                            isClick = true;
                            Drawable drawable = context.getResources().getDrawable(R.drawable.icon_notify_ble_data_blue);
                            callback.CharacteristicNotify(characteristic);
                            //v.setBackground(drawable);
                            ((ImageView)v).setImageResource(R.drawable.icon_notify_ble_data_blue);
                        }else {
                            isClick = false;
                            Drawable drawable = context.getResources().getDrawable(R.drawable.icon_notify_ble_data_gray);
                            callback.closeNotify(characteristic);
                            // v.setBackground(drawable);
                            ((ImageView)v).setImageResource(R.drawable.icon_notify_ble_data_gray);
                        }

                    }
                }
            });
        }
        return convertView;
    }


    public String getCharacterProperties(int properties) {
        String propertiesStr = "";
        if ((properties & BluetoothGattCharacteristic.PROPERTY_BROADCAST) == BluetoothGattCharacteristic.PROPERTY_BROADCAST) {
            propertiesStr += "BROADCAST,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_READ) == BluetoothGattCharacteristic.PROPERTY_READ ) {
            propertiesStr += "READ,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) {
            propertiesStr += "W_N_RESP,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) == BluetoothGattCharacteristic.PROPERTY_WRITE) {
            propertiesStr += "WRITE,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == BluetoothGattCharacteristic.PROPERTY_NOTIFY) {
            propertiesStr += "NOTIFY,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == BluetoothGattCharacteristic.PROPERTY_INDICATE) {
            propertiesStr += "INDICATE,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) == BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) {
            propertiesStr += "SIGNED_WRITE,";
        }
        if ((properties & BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) == BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) {
            propertiesStr += "EXTENDED_PROPS,";
        }
        return propertiesStr;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }


    static class GroupViewHolder {

         LinearLayout mLlBtServiceInfo;
         TextView mTvBtServiceName;
         TextView mTvBtServiceUuid;

    }

    static class ChildViewHolder {
         TextView mTvBtCharName;
         ImageView mIvUpArrow;
         ImageView mIvDownArrow;
         ImageView mIvNotify;
         TextView mTvBtCharUuid;
         TextView mTvProperties;

    }
}
